package factory.one.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {

    public SpringSecurityConfig() {
        super();
    }

    /**
     * ADMIN-管理员 SALE-销售 WORKER-生产者 FINANCE-财务
     */
    @Bean
    public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
        http
                .formLogin()
                .loginPage("/login.html")
                .failureUrl("/login-error.html")
                .and()
                .logout()
                .logoutSuccessUrl("/index.html")
                .and()
                .authorizeRequests()
                .mvcMatchers("/sale/**").hasAnyRole("SALE", "ADMIN")
                .mvcMatchers("/work/**").hasAnyRole("WORKER", "ADMIN")
                .mvcMatchers("/send/**").hasAnyRole("WORKER", "ADMIN")
                .mvcMatchers("/deliver/**").hasAnyRole("WORKER", "SALE", "ADMIN")
                .mvcMatchers("/finance/**").hasAnyRole("FINANCE", "ADMIN")

                .mvcMatchers("/custom/**").hasAnyRole("ADMIN", "SALE")
                .mvcMatchers("/product/**").hasAnyRole("ADMIN", "SALE", "WORKER")

                .mvcMatchers("/admin/**").hasRole("ADMIN")
                .mvcMatchers("/order/**").hasRole("ADMIN")

                .mvcMatchers("/user/list.html").hasRole("ADMIN")
                .mvcMatchers("/user/add.html").hasRole("ADMIN")
                .mvcMatchers("/user/add").hasRole("ADMIN")
                .mvcMatchers("/user/edit.html").hasRole("ADMIN")
                .mvcMatchers("/user/edit").hasRole("ADMIN")
                .mvcMatchers("/user/changePassword.html").permitAll()
                .mvcMatchers("/user/changePassword").permitAll()
                .and()
                .exceptionHandling()
                .accessDeniedPage("/403.html")
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .maximumSessions(1)
                .expiredUrl("/login.html")
                .and()
                .invalidSessionUrl("/login.html")
                .sessionFixation()
                .migrateSession();

        return http.build();
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(4);
    }

    //    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withUsername("admin").password("{noop}admin").roles("ADMIN").build(),
                User.withUsername("jim").password("{noop}demo").roles("ADMIN").build(),
                User.withUsername("bob").password("{noop}demo").roles("USER").build(),
                User.withUsername("ted").password("{noop}demo").roles("USER", "ADMIN").build());
    }

}
